[小ネタ] CDK(Python)で CfnBucketにバケットポリシーを付与する
AWS Cloud Development Kit (CDK) の強みに High Level Construct でより簡単にリソースが定義できるところがあります。
一方で CloudFormationのリソースと 1対1 で対応する Low Level Construct(CFNリソース) も扱えます。 High Level Construct が対応していないリソースや、 要件がしっかり固まっている場合などは、こちらを使用することがおすすめです。
(個人的には CFNリソースだけでもプログラムでインフラを書いていけるメリットは 十分に感じています。CloudFormationのほうがやってみた記事・ブログが 多いので、それらを参考にしながらCDKで書くことができます。)
今回は CFNリソースの s3.CfnBucket にバケットポリシーを付与してみます。 内容自体はシンプルですが少し迷うところがあったので備忘録として残します。
目次
環境
CDKインストールとセットアップ詳細は割愛します (以下の AWS Workshopや 弊社ブログを参照ください)
環境は以下のとおり
- cdk: 1.20.0
- Python: 3.7.3
やること
CfnBucket で作成した S3バケットにバケットポリシーを付与します。
今回は Application Load Balancer がアクセスログを S3に格納するときに必要になる、 以下のバケットポリシーを付与します。 (東京リージョンを想定)
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::(aws-account-id):root" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::(bucket-name)/(prefix)/*" } ] }
参考: Application Load Balancer のアクセスログ > バケットのアクセス許可
(aws-account-id)
にはALBのリージョンに対応する AWSアカウントID、
(bucket-name)/(prefix)
にはバケット名とプレフィクスが入ります。
やってみた
以下 requirements.txt
と app.py
を作成しました。
aws-cdk.core aws-cdk.aws-s3 aws-cdk.aws-iam
#!/usr/bin/env python3 from aws_cdk import ( core, aws_iam as iam, aws_s3 as s3, ) class CfnBucketWithPolicyStack(core.Stack): def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) bucket_name = "cfn-bucket-with-policy-test-abcdefg" bucket_prefix = "alb-log" elb_account_id = "582318560864" # ポリシー作成 policy_statement = iam.PolicyStatement() policy_statement.add_aws_account_principal(elb_account_id) policy_statement.add_actions("s3:PutObject") policy_statement.add_resources( "arn:aws:s3:::{0}/{1}/*".format(bucket_name, bucket_prefix)) policy_document = iam.PolicyDocument( statements=[policy_statement] ) # S3 バケット(CfnBucket) bucket = s3.CfnBucket( self, "Bucket", bucket_name=bucket_name ) # バケットポリシー(CfnBucketPolicy) s3.CfnBucketPolicy( self, "BucketPolicy", bucket=bucket.ref, policy_document=policy_document.to_json() ) # スタック作成 app = core.App() CfnBucketWithPolicyStack(app, "CfnBucketWithPolicyStack") app.synth()
スタック作成
1. pip install -r requirements.txt
で必要なパッケージをインストールします。
2. cdk ls
でスタック一覧を確認して、
$ cdk ls CfnBucketWithPolicyStack
3. cdk deploy
でスタックを作成します。
確認
マネジメントコンソールから作成されたバケットのバケットポリシーを見てみます。
所望のバケットポリシーになっていることを確認できました。
app.py 詳細
使用したクラスは以下の通り。
- バケット作成
- バケットポリシー作成
▼ iam.PolicyDocument 部分
bucket_name = "cfn-bucket-with-policy-test-abcdefg" bucket_prefix = "alb-log" elb_account_id = "582318560864" # ポリシー作成 policy_statement = iam.PolicyStatement() policy_statement.add_aws_account_principal(elb_account_id) policy_statement.add_actions("s3:PutObject") policy_statement.add_resources( "arn:aws:s3:::{0}/{1}/*".format(bucket_name, bucket_prefix)) policy_document = iam.PolicyDocument( statements=[policy_statement] )
後述する CfnBucketPolicy
のコンストラクタ引数:
policy_document
にバケットポリシーを入れるためのポリシー作成です。
aws_iam.PolicyStatement
を作成し、
以下メソッドでステートメント情報を入れていきます。
- add_aws_account_principal: プリンシパルの追加
- add_actions: アクションの追加
- add_resources: リソースの追加
このステートメントをもとに、 aws_iam.PolicyDocument
を作成します。
▼ s3.CfnBucketPolicy 部分
# バケットポリシー(CfnBucketPolicy) s3.CfnBucketPolicy( self, "BucketPolicy", bucket=bucket.ref, policy_document=policy_document.to_json() )
policy_document=policy_document.to_json()
の部分でバケットポリシーを指定します。
おわりに
s3.CfnBucketPolicy のドキュメントを見ても、 policy_document
の型
が Any
なのでどんなデータを入れたら良いのかいまいち分からなかったのが
本ブログのモチベーションでした。
この記事が少しでもどなたかのお役に立てば幸いです。